package edu.ucla.cs.typecast.app.auction;

import java.io.*;
import java.util.*;

import edu.ucla.cs.typecast.net.NetUtil;

import junit.framework.TestCase;

public class AuctionTestCase extends TestCase {
	protected static final String DEFAULT_ADDR = "239.255.10.10";
	
	protected static final int DEFAULT_PORT = 5265;
	
	protected void shortSleep() {
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			// Print error message
			e.printStackTrace();
		}
	}
	
	public void test(Player seller1, Player buyer1, Player buyer2) throws IOException {
		// Seller 1 opens an auction
		// The buyers should all see the auction with Seller 1 as the seller
		
		ItemInfo item1Info = new ItemInfo(1, "New IBM Thinkpad X61");
		seller1.openAuction(item1Info, 1000, new Date(new Date().getTime() + 10000));
		shortSleep();
		
		assertEquals(1, seller1.getAuctionInfoList().size());
		
		assertEquals(1, buyer1.getAuctionInfoList().size());
		assertEquals(seller1.getInfo(), buyer1.getAuctionInfoList().first().getSellerInfo());
		assertEquals(item1Info, buyer1.getAuctionInfoList().first().getItemInfo());
		assertEquals(1, buyer2.getAuctionInfoList().size());
		assertEquals(seller1.getInfo(), buyer2.getAuctionInfoList().first().getSellerInfo());
		assertEquals(item1Info, buyer2.getAuctionInfoList().first().getItemInfo());		
		
		// Buyer 1 makes a bid of $950, which is not enough to make him the highest bidder
		
		buyer1.bid(seller1.getInfo(), item1Info, 950);
		shortSleep();
		
		assertEquals(1000, seller1.getAuctionInfoList().first().getPrice());
		assertEquals(null, seller1.getAuctionInfoList().first().getHighestBidderInfo());
		assertEquals(1000, buyer2.getAuctionInfoList().first().getPrice());
		assertEquals(null, buyer2.getAuctionInfoList().first().getHighestBidderInfo());
		
		// Buyer 1 makes a bid of $1050, which makes him the highest bidder
		
		buyer1.bid(seller1.getInfo(), item1Info, 1050);
		shortSleep();
		
		assertEquals(1050, seller1.getAuctionInfoList().first().getPrice());
		assertEquals(buyer1.getInfo(), seller1.getAuctionInfoList().first().getHighestBidderInfo());
		assertEquals(1050, buyer1.getAuctionInfoList().first().getPrice());
		assertEquals(buyer1.getInfo(), buyer1.getAuctionInfoList().first().getHighestBidderInfo());
		assertEquals(1050, buyer2.getAuctionInfoList().first().getPrice());
		assertEquals(buyer1.getInfo(), buyer2.getAuctionInfoList().first().getHighestBidderInfo());
		
		// Buyer 2 makes a bid of $1100, which makes him the highest bidder
		
		buyer2.bid(seller1.getInfo(), item1Info, 1100);
		shortSleep();
		
		assertEquals(1100, seller1.getAuctionInfoList().first().getPrice());
		assertEquals(buyer2.getInfo(), seller1.getAuctionInfoList().first().getHighestBidderInfo());
		assertEquals(1100, buyer1.getAuctionInfoList().first().getPrice());
		assertEquals(buyer2.getInfo(), buyer1.getAuctionInfoList().first().getHighestBidderInfo());
		assertEquals(1100, buyer2.getAuctionInfoList().first().getPrice());
		assertEquals(buyer2.getInfo(), buyer2.getAuctionInfoList().first().getHighestBidderInfo());
		
		// Seller closes auction
		// Buyer 2 wins
		
		seller1.closeAuction(item1Info);
		shortSleep();
		
		assertEquals(1, buyer2.getWonItems().size());
		
		assertTrue(buyer2.getWonItems().contains(item1Info));
	}

	public void test() throws IOException {
		ParticipantInfo seller1Info = new ParticipantInfo(2001, "Seller 1", NetUtil.getLocalHost(), 2001);
		Player seller1 = new PlayerImpl(seller1Info, DEFAULT_ADDR, DEFAULT_PORT);
		
		ParticipantInfo buyer1Info = new ParticipantInfo(3001, "Buyer 1", NetUtil.getLocalHost(), 3001);
		Player buyer1 = new PlayerImpl(buyer1Info, DEFAULT_ADDR, DEFAULT_PORT);
		
		ParticipantInfo buyer2Info = new ParticipantInfo(3002, "Buyer 2", NetUtil.getLocalHost(), 3002);
		Player buyer2 = new PlayerImpl(buyer2Info, DEFAULT_ADDR, DEFAULT_PORT);
		
		test(seller1, buyer1, buyer2);
	}
}
